package main

import (
	"bytes"
	"errors"
	"fmt"
	"image/jpeg"
	"image/png"
	"os/exec"

	"image"
	// "image/jpeg"
	// "image/png"

	"os"
	"path"
	"strings"

	"github.com/chai2010/webp"
	"github.com/nfnt/resize"
	log "github.com/sirupsen/logrus"
	"golang.org/x/image/bmp"
)

/**压缩并保存图片
 */
func compressImage(imgPath string, OutOriginalFilePath string, outWebpFilePath string, size *Resize) (err error) {
	data, err := os.ReadFile(imgPath)
	if err != nil {
		log.Errorln(err)
	}
	var img image.Image
	contentType := getFileContentType(data[:512])
	ImageType := ""
	if strings.Contains(contentType, "jpeg") {
		ImageType = "jpeg"
		img, err = jpeg.Decode(bytes.NewReader(data))
	} else if strings.Contains(contentType, "png") {
		ImageType = "png"
		img, err = png.Decode(bytes.NewReader(data))
	} else if strings.Contains(contentType, "bmp") {
		ImageType = "bmp"
		img, err = bmp.Decode(bytes.NewReader(data))
	} else if strings.Contains(contentType, "gif") {
		ImageType = "gif"
		if !imageExists(outWebpFilePath) {
			fmt.Println("gif转码路径", imgPath, outWebpFilePath)

			err := os.MkdirAll(path.Dir(outWebpFilePath), 0755)
			if err != nil {
				log.Error(err)
				return errors.New("创建目录失败")
			}
			cmd := exec.Command("./gif2webp", "-lossy", "-q", fmt.Sprint(size.Quality), imgPath, "-o", outWebpFilePath)
			cmdBuf, err := cmd.Output()
			if err != nil {
				fmt.Println(err.Error())
			}
			fmt.Println("gif转码", string(cmdBuf))
		}
		return nil
	}
	if err != nil || img == nil {
		errinfo := fmt.Sprintf("解码图片 %s 失败: %v", imgPath, err)
		log.Errorln(errinfo)
		return errors.New(errinfo)
	}

	var maxWidth, maxHeight uint

	if size.Width > 0 && size.Height > 0 && (size.Width < webpMax || size.Height < webpMax) {
		maxWidth = size.Width
		maxHeight = size.Height
	} else {
		maxWidth = webpMax
		maxHeight = webpMax
	}
	// maxWidth = size.Width
	// maxHeight = size.Height
	miniImg, err := MakeResize(data, ImageType, maxWidth, maxHeight)
	if err != nil {
		log.Errorln(err)
		return err
	}
	if !imageExists(OutOriginalFilePath) {
		SaveImage(miniImg, OutOriginalFilePath, ImageType, size)
	}
	if !imageExists(outWebpFilePath) {
		SaveImage(miniImg, outWebpFilePath, "webp", size)
	}
	return err

}

/*
*
创建缩略图
*/
func MakeResize(Data []byte, ImageType string, width uint, height uint) (out image.Image, err error) {
	var img image.Image

	reader := bytes.NewReader(Data)
	// reader2 := bytes.NewReader(Data)
	switch ImageType {
	case "jpeg":
		img, _ = jpeg.Decode(reader)
	case "png":
		img, _ = png.Decode(reader)
	case "bmp":
		img, _ = bmp.Decode(reader)
	case "gif":
		// 这里不对gif压缩
	}
	if img == nil {
		msg := "不支持压缩的文件类型"
		err = errors.New(msg)
		return nil, err
	}
	if ImageType == "gif" {
		return img, nil
	}
	miniImg := resize.Thumbnail(width, height, img, resize.NearestNeighbor)
	// miniImg := resize.Resize(width, height, img, resize.Lanczos3)

	return miniImg, nil
}

func SaveImage(img image.Image, imgPath string, ImageType string, size *Resize) error {
	// 文件已存在
	if imageExists(imgPath) {
		return errors.New("文件已存在")
	}

	buffer := new(bytes.Buffer)
	var err error
	switch ImageType {
	case "jpeg":
		err = jpeg.Encode(buffer, img, &jpeg.Options{Quality: int(size.Quality)})
	case "png":
		err = png.Encode(buffer, img)
	case "bmp":
		err = bmp.Encode(buffer, img)
	case "gif":
		break
	case "webp":
		// Lossless:true 无损
		// err = webp.Encode(buffer, img, &webp.Options{Lossless: true, Quality: float32(size.Quality)})
		webpData, err := webp.EncodeRGBA(img, float32(size.Quality))
		if err != nil {
			log.Error("转码失败", err)
			return errors.New("文件已存在")
		}
		WriteFile(imgPath, webpData)
		return nil
	}
	if err != nil {
		log.Error("转码失败", err)
		return errors.New("文件已存在")
	}

	WriteFile(imgPath, buffer.Bytes())
	return nil
}
func WriteFile(filePath string, data []byte) error {
	err := os.MkdirAll(path.Dir(filePath), 0755)
	if err != nil {
		log.Error(err)
		return errors.New("创建目录失败")
	}
	if err := os.WriteFile(filePath, data, 0644); err != nil {
		log.Error(err)
		return errors.New("写入失败")
	}
	return nil
}
